﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using DbView.Resources;

namespace SqliteDriver
{
/*
	Sql Server Settings are held in the <SqlServer> element of the main config file
	No need to load as the config file is loaded at boot-up
*/
	public class SqlServerSettingsMgr
	{
		const String SQLSERVERNODE = "SqlServer";
		public const String SQLSERVER_SETTING_PROFILER = "ProfilerConfiguration";
		public const String SQLSERVER_SETTING_PROFILER_LASTUSED = "__LastUsed";
		public const String SQLSERVER_SETTING_PROFILER_PRESET_ROOT = "__Preset";
		public const String SQLSERVER_SETTING_PROFILER_ATT_NAME = "name";

		// the singleton object
		static SqlServerSettingsMgr theImplementation = null;

		// access to the singleton
		public static SqlServerSettingsMgr Instance
		{
			get
			{
				if (theImplementation == null)
					theImplementation = new SqlServerSettingsMgr();
				return theImplementation;
			}
		}

		public SqlServerSettingsMgr()
		{
		}

		public XmlNodeList GetValues(String settingName)
		{
			String xpath = String.Format("//{0}/{1}", SQLSERVERNODE, settingName);
			XmlNodeList nodes = ConfigDoc.Instance.SelectNodes(xpath);
			return nodes;
		}

		public String GetValue(String settingName)
		{
			String xpath = String.Format("//{0}/{1}", SQLSERVERNODE, settingName);
			XmlNode settingNode = ConfigDoc.Instance.SelectSingleNode(xpath);
			if (settingNode != null) return settingNode.InnerText;
			return "";
		}

		public void SetValue(String settingName, String value, bool setAsCData)
		{
			XmlNode node = SettingsNode();
			String xpath = settingName;
			XmlNode settingNode = node.SelectSingleNode(xpath);
			if (settingNode == null)
			{
				//settingNode = nsNode.OwnerDocument.CreateElement(settingName);
				//nsNode.AppendChild(settingNode);
				settingNode = ConfigDoc.CreateSettingNode(node, settingName);
			}
			// set as CData for Xml so it reads better in the file
			if (setAsCData)
			{
				settingNode.RemoveAll();
				settingNode.AppendChild(settingNode.OwnerDocument.CreateCDataSection(value));
			}
			else
				settingNode.InnerText = value;
		}

		public bool Load()
		{
			// no need to load as it is done with load of main config file
			// here in case they are moved out of the main config file.
			return true;
		}

		public void Save()
		{
			// for future developments
			ConfigDoc.Instance.SaveConfig();
		}
		
		internal static XmlNode SettingsNode()
		{
			// search doc for settings
			String xpath = String.Format("//{0}", SQLSERVERNODE);
			XmlNode settingsNode = ConfigDoc.Instance.SelectSingleNode(xpath);
			if (settingsNode == null)
			{
				// search for doc element.
				xpath = String.Format("//{0}", ConfigDoc.CFGELM_DOC);
				XmlNode docNode = ConfigDoc.Instance.SelectSingleNode(xpath);
				// bootstrap. Ignore settings for now. 
				if (docNode == null) return null;
				settingsNode = docNode.OwnerDocument.CreateElement(SQLSERVERNODE);
				// add to end of config.
				docNode.AppendChild(settingsNode);
			}
			return settingsNode;
		}
	}

	public class ProfilerSettings
	{
		public static String[] Settings
		{
			get
			{
				XmlNodeList nodeList = SqlServerSettingsMgr.Instance.GetValues(SqlServerSettingsMgr.SQLSERVER_SETTING_PROFILER);
				XmlNode node = (nodeList == null || nodeList.Count == 0) ? null : nodeList[0];
				if (node == null || !node.HasChildNodes) return new String[0];
				String [] settings = new String[node.ChildNodes.Count];
				int idx = 0;
				foreach (XmlNode child in node.ChildNodes)
				{
					settings[idx++] = child.InnerText;
				}
				return settings;
			}
		}

		public static String Get(String key)
		{
			SqlServerSettingsMgr mgr = new SqlServerSettingsMgr();
			String xpath = String.Format("{0}/{1}", SqlServerSettingsMgr.SQLSERVER_SETTING_PROFILER, key);
			return mgr.GetValue(xpath);
		}

		public static void Update(String key, String settingsXml)
		{
			SqlServerSettingsMgr mgr = new SqlServerSettingsMgr();
			String xpath = String.Format("{0}/{1}", SqlServerSettingsMgr.SQLSERVER_SETTING_PROFILER, key);
			mgr.SetValue(xpath, settingsXml, true);
		}

		internal static bool CheckAndUpgrade()
		{
			XmlNode settingsNode = SqlServerSettingsMgr.SettingsNode();
			if (settingsNode == null) return false; // nothing to do
			String content = settingsNode.InnerText;
			// there is content in this node, but there is no mention of the new default config tab
			if (content.Length > 0 && content.IndexOf(SqlServerSettingsMgr.SQLSERVER_SETTING_PROFILER_LASTUSED) == -1)
			{
				// clear old content
				// write it to __LastUsed
				settingsNode.RemoveAll();
				// hack fixup
				content = content.Replace("profileconfiguration", SqlServerSettingsMgr.SQLSERVER_SETTING_PROFILER_LASTUSED);
				Update(SqlServerSettingsMgr.SQLSERVER_SETTING_PROFILER_LASTUSED, content);
				return true;  // done!
			}
			return false;
		}
	}
}
